package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.form.ScPriceconfMileForm;
import cn.huiyunche.base.service.interfaces.ScPriceconfMileService;
import cn.huiyunche.base.service.mappers.ScPriceconfMileMapper;
import cn.huiyunche.base.service.mappers.ext.ScPriceconfMileExtMapper;
import cn.huiyunche.base.service.model.ScPriceconfMile;
import cn.huiyunche.base.service.model.ScPriceconfMileExample;
import cn.huiyunche.base.service.query.ScPriceconfMileQueryConditions;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.ScPriceconfMileVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @FileName: cn.huiyunche.base.service.interfaces.impl
 * @Description: Description
 * @author: Aaron
 * @date: 2017/3/13 下午4:59
 */
@Service
public class ScPriceconfMileServiceImpl implements ScPriceconfMileService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScPriceconfMileServiceImpl.class);

    @Autowired
    private ScPriceconfMileMapper scPriceconfMileMapper;

    @Autowired
    private ScPriceconfMileExtMapper scPriceconfMileExtMapper;

    @Override
    public Integer add(ScPriceconfMileForm form, BindingResult br) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.add param : {}", form);

        if (form == null) {
            LOGGER.error("ScPriceconfMileServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("表单不能为空");
        }

        //表单验证
        verificationForm(br);

        //业务验证
        verificationBusiness(form);

        //查询当前生效的记录，更新失效时间未添加记录的生效时间
        ScPriceconfMile currentMile = this.selectByEffectiveDateAndRouteId(form.getRouteId(), new Date());
        if (null != currentMile) {
            currentMile.setInvalidDate(form.getEffectiveDate());
            this.updateSelective(currentMile);
        }

        ScPriceconfMile mile = new ScPriceconfMile();
        BeanUtils.copyProperties(form, mile);

        return scPriceconfMileMapper.insertSelective(mile);
    }

    private void verificationBusiness(ScPriceconfMileForm form) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.verificationBusiness param : {}", form);

        List<ScPriceconfMile> list = this.selectByRouteId(form.getRouteId());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        /**
         * 是否已经存在未激活的里程变动
         * 激活时间大于
         */
        List<ScPriceconfMile> collect = list.stream().filter(
                o -> -1 != o.getEffectiveDate().compareTo( new DateTime().withMillisOfDay(0).toDate() )
                ).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(collect)) {

            if ( null != form.getId() ){
                if ( CollectionUtils.isNotEmpty(collect.stream().filter( o -> o.getId() == form.getId() ).collect(Collectors.toList())) ) {
                    return ;
                }
            }

            if ( 1 < collect.size()) {
                LOGGER.error("ScPriceconfMileServiceImpl.verificationBusiness already exist not active record");
                throw new BusinessException("线路里程已经存在未生效的记录");
            }

            ScPriceconfMile mile = collect.get(0);
            if (null != form.getId() && form.getId() == mile.getId()) {
                return ;
            }
            if ( form.getEffectiveDate().compareTo(mile.getEffectiveDate()) == 1 ){
                return ;
            }

            LOGGER.error("ScPriceconfMileServiceImpl.verificationBusiness already exist not active record");
            throw new BusinessException("线路里程已经存在未生效的记录");
        }
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            LOGGER.error("ScPriceconfMileServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("ScPriceconfMileServiceImpl.verificationForm error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    @Override
    public void update(ScPriceconfMileForm form, BindingResult br) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.update param : {}", form);

        if (form == null) {
            LOGGER.error("ScPriceconfMileServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("表单不能为空");
        }

        //表单验证
        verificationForm(br);

        //业务验证
        verificationBusiness(form);

        //查询当前生效的记录，更新失效时间未添加记录的生效时间
        ScPriceconfMile currentMile = this.selectByEffectiveDateAndRouteId(form.getRouteId(), new Date());
        if (null != currentMile) {
            currentMile.setInvalidDate(form.getEffectiveDate());
            this.updateSelective(currentMile);
        }

        ScPriceconfMile mile = new ScPriceconfMile();
        BeanUtils.copyProperties(form, mile);

        this.updateSelective(mile);
    }

    @Override
    public void updateSelective(ScPriceconfMile mile) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.updateSelective param : {}", mile);

        if (null == mile) {
            LOGGER.error("ScPriceconfMileServiceImpl.updateSelective param mile must not be null");
            throw new IllegalArgumentException("线路价格变动不能为空");
        }

        scPriceconfMileMapper.updateByPrimaryKeySelective(mile);
    }

    @Override
    public void del(Integer id) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.del param : {}", id);

        if ( null == id || 0 == id.intValue() ) {
            LOGGER.error("ScPriceconfMileServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }


        ScPriceconfMile mile = selectByPrimaryKey(id);
        if ( null == mile ){
            LOGGER.error("ScPriceconfMileServiceImpl.del mile is null");
            throw new BusinessException("记录不存在");
        }

        Date today = new DateTime().withMillisOfDay(0).toDate();
        if ( 1 != mile.getEffectiveDate().compareTo(today)  ) {
            LOGGER.error("ScPriceconfMileServiceImpl.del mile can not delete");
            throw new BusinessException("只能删除未生效的记录");
        }

        scPriceconfMileMapper.deleteByPrimaryKey(id);

        //更新当前记录失效时间为空
        ScPriceconfMile currentMile = this.selectByEffectiveDateAndRouteId(mile.getRouteId(), new Date());
        if ( null != currentMile ) {
            currentMile.setInvalidDate(null);
            scPriceconfMileMapper.updateByPrimaryKey(currentMile);
        }
    }

    @Override
    public ScPriceconfMile selectByEffectiveDateAndRouteId(Integer routeId, Date effectiveDate) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.selectByEffectiveDate params : {}, {}", routeId, effectiveDate);

        if (effectiveDate == null) {
            LOGGER.error("ScPriceconfMileServiceImpl.selectByEffectiveDate param effectiveDate must not be null");
            throw new IllegalArgumentException("生效时间不能为空");
        }

        ScPriceconfMileExample example = new ScPriceconfMileExample();
        example.createCriteria().andRouteIdEqualTo(routeId)
                .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                .andInvalidDateIsNull();

        List<ScPriceconfMile> list = scPriceconfMileMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(list)) {
            ScPriceconfMileExample example1 = new ScPriceconfMileExample();
            example1.createCriteria().andRouteIdEqualTo(routeId)
                    .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                    .andInvalidDateGreaterThan(effectiveDate);

            list = scPriceconfMileMapper.selectByExample(example1);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }

    @Override
    public List<ScPriceconfMile> selectByRouteId(Integer routeId) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.selectByRouteId param : {}", routeId);

        if (null == routeId || 0 == routeId.intValue()) {
            LOGGER.error("ScPriceconfMileServiceImpl.selectByRouteId param routeId must not be null");
            throw new BusinessException("线路主键不能为空");
        }

        ScPriceconfMileExample example = new ScPriceconfMileExample();
        example.createCriteria().andRouteIdEqualTo(routeId);

        return scPriceconfMileMapper.selectByExample(example);
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, ScPriceconfMileQueryConditions conditions) throws Exception {
        if (null == conditions) {
            LOGGER.error("ScPriceconfMileServiceImpl.selectListByConditions param conditions must not be null");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " pm.gmt_create DESC";
        }

        Map<String, Object> paramsMap = new HashedMap();

        if (null != conditions.getoProvinceId()) {
            paramsMap.put("o_province_code", conditions.getoProvinceId());
        }

        if (StringUtils.isNotBlank(conditions.getoTag())) {
            paramsMap.put("o_tag", "%" + conditions.getoTag() + "%");
        }

        if (null != conditions.getdProvinceId()) {
            paramsMap.put("d_province_code", conditions.getdProvinceId());
        }

        if (StringUtils.isNotBlank(conditions.getdTag())) {
            paramsMap.put("d_tag", "%" + conditions.getdTag() + "%");
        }

        if (null != conditions.getCurrentValue()) {
            paramsMap.put("current_value", conditions.getCurrentValue());
        }

        if (null != conditions.getEffectiveDate()) {
            paramsMap.put("effective_date", conditions.getEffectiveDate());
        }

        if (null != conditions.getInvalidDate()) {
            paramsMap.put("invalid_date", conditions.getInvalidDate());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(scPriceconfMileExtMapper.countByConditions(paramsMap));
            paramsMap.put("limitStart", pageVo.getStartIndex());
            paramsMap.put("limitEnd", pageVo.getPageSize());
            paramsMap.put("orderByClause", orderByClause);
        }

        List<ScPriceconfMileVo> list = scPriceconfMileExtMapper.selectByConditions(paramsMap);

        //更新标示
        if ( CollectionUtils.isNotEmpty(list) ) {
            Date today = new DateTime().withMillisOfDay(0).toDate();
            list.stream().forEach( o -> {
                if ( 1 != o.getEffectiveDate().compareTo(today) ) {
                    o.setIsLock(true);
                }
            } );
        }
        map.put("list", list);

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public ScPriceconfMile selectByPrimaryKey(Integer id) throws Exception {
        LOGGER.info("ScPriceconfMileServiceImpl.selectByPrimaryKey param : {}", id);

        if (null == id || 0 == id.intValue()) {
            LOGGER.error("ScPriceconfMileServiceImpl.selectByPrimaryKey param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        return scPriceconfMileMapper.selectByPrimaryKey(id);
    }

}
